package com.xinchao.schedule;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xinchao.core.constant.BusinessConstant;
import com.xinchao.core.constant.CmccApiConstant;
import com.xinchao.core.constant.DateFormatConstant;
import com.xinchao.core.exception.CmccApiException;
import com.xinchao.core.exception.ServiceException;
import com.xinchao.core.util.CmccApiUtils;
import com.xinchao.core.util.DateUtils;
import com.xinchao.model.dto.CityCmccInfoDTO;
import com.xinchao.model.dto.DeviceSimInfoActivationTimeDTO;
import com.xinchao.model.dto.DeviceSimInfoTrafficDTO;
import com.xinchao.service.CityCmccInfoService;
import com.xinchao.service.DeviceSimInfoService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 终端sim卡信息定时任务(从中国移动获取“激活时间”、“当月流量预警”、“历史总流量”)
 *
 * @author dxy
 * @date 2018/8/15 15:21
 */
@Component
public class DeviceSimInfoSchedule {
	private static Logger logger = LoggerFactory.getLogger(DeviceSimInfoSchedule.class);
	@Autowired
	private DeviceSimInfoService deviceSimInfoService;
	@Autowired
	private CityCmccInfoService cityCmccInfoService;


	/**
	 * 更新终端sim卡信息激活时间、号码（mssidn）；在获取激活时间是，也把sim卡的mssidn信息一起查询出来，在中国移动数据库里，iccid与mssidn是绑定的
	 * 每天凌晨5分执行
	 */
	// @Scheduled(cron = "0 0/3 * * * ?")
//	@Scheduled(cron = "0 5 0 * * ?")
	public void updateDeviceSimInfoActivationTime() {
		//4.1.1.1.9	批量号码激活时间查询
		String method = "triopi.member.actitime.batch.query";
		try {
			//城市对应的集团编码，应用键对应值，密钥的MAP
			Map<String, CityCmccInfoDTO> cityCmccInfoMap = cityCmccInfoService.getCityCmccInfoMap();
			System.out.println("cityCmccInfoMap: " + cityCmccInfoMap.toString());
			StringBuilder sb = new StringBuilder();
			if (cityCmccInfoMap != null && cityCmccInfoMap.size() > 0) {
				Set<String> citySet = cityCmccInfoMap.keySet();
				for (String city : citySet) {
					//获取城市对应的集团编码，应用键对应值，密钥
					CityCmccInfoDTO cityCmccInfoDTO = cityCmccInfoMap.get(city);
					//应用键,由中国移动提供
					String appKeyValue = cityCmccInfoDTO.getAppKey();
					//加密密钥，由中国移动提供
					String secrect = cityCmccInfoDTO.getSecrect();
					//10位集团编码，由中国移动提供
					String groupCode = cityCmccInfoDTO.getGroupCode();
					System.out.println("updateDeviceSimInfoActivationTime_start_time:" + DateUtils.longTimeStampToStringDate(System.currentTimeMillis(), DateFormatConstant.LONG_DATE_FORMAT_STR_CH));
					//获取终端sim卡没有激活时间总数
					Long count = deviceSimInfoService.countDeviceSimInfoNoActivationTime(city);
					System.out.println("updateDeviceSimInfoActivationTime_count: " + count);
					while (count > 0) {
						Long startRow = 0L;
						//默认结束ID(因为移动批量查询数是100，所以此次定义100)
						long endRow = 100L;
						System.out.println("startRow:" + startRow);
						System.out.println("endRow:" + endRow);
						//以为在查询sql语句中，按照
						List<DeviceSimInfoActivationTimeDTO> activationTimeList = deviceSimInfoService.listDeviceSimInfoActivationTime(city, startRow, endRow);
						System.out.println("updateDeviceSimInfoActivationTime_activationTimeList_size: " + activationTimeList.size());
						if (CollectionUtils.isNotEmpty(activationTimeList)) {
							//将iccid拼接整字符串，用逗号隔开
							for (int j = 0; j < activationTimeList.size(); j++) {
								DeviceSimInfoActivationTimeDTO dto = activationTimeList.get(j);
								String iccid = dto.getIccid();
								if (j > 0) {
									sb.append(",");
								}
								sb.append(iccid);
							}
							String iccids = sb.toString();
							System.out.println("updateDeviceSimInfoActivationTime_iccids: " + iccids);
							//将iccidSb的长度清零，重复使用
							sb.setLength(0);
							//调用移动接口，获取sim卡激活时间、mssidn
							String data = CmccApiUtils.queryByICCID(method, iccids, true, "", appKeyValue, secrect, groupCode);
							System.out.println("updateDeviceSimInfoActivationTime_data: " + data);
							//转化为JSONObject
							JSONObject dataJsonObj = JSON.parseObject(data);
							//获取msisdnList
							JSONObject msisdnJsonObj = dataJsonObj.getJSONObject(CmccApiConstant.JSON_KEY_MSISDN_LIST);
							if (msisdnJsonObj != null) {
								JSONArray jsonArray = msisdnJsonObj.getJSONArray(CmccApiConstant.JSON_KEY_LIST);
								if (jsonArray != null && jsonArray.size() > 0) {
									List<DeviceSimInfoActivationTimeDTO> list = new ArrayList<>();
									for (int j = 0; j < jsonArray.size(); j++) {
										JSONObject jsonObject = jsonArray.getJSONObject(j);
										DeviceSimInfoActivationTimeDTO activationTime = new DeviceSimInfoActivationTimeDTO();
										activationTime.setActivationTime(jsonObject.getString(CmccApiConstant.JSON_KEY_TIME));
										activationTime.setIccid(jsonObject.getString(CmccApiConstant.JSON_KEY_ICCID));
										activationTime.setMsisdn(jsonObject.getString(CmccApiConstant.JSON_KEY_MSISDN));
										list.add(activationTime);
									}
									//保存激活时间到数据库
									if (CollectionUtils.isNotEmpty(list)) {
										for (DeviceSimInfoActivationTimeDTO dto : list) {
											deviceSimInfoService.updateDeviceSimInfoActivationTime(dto);
										}
									}
								}
							}
						}
						//更新完没有激活时间的数据后，再查询总数
						count = deviceSimInfoService.countDeviceSimInfoNoActivationTime(city);
						//如果查询返回为null置为0L
						if (count == null) {
							count = 0L;
						}
					}
				}
			}
		} catch (ServiceException e) {
			logger.error("DeviceSimInfoSchedule updateDeviceSimInfoActivationTime 更新终端sim卡信息激活时间失败：" + e.getMessage());
		} catch (CmccApiException e) {
			logger.error("DeviceSimInfoSchedule updateDeviceSimInfoActivationTime 更新终端sim卡信息激活时间失败：" + e.getMessage());
		}
	}

	/**
	 * 更新终端sim卡信息当月流量预警
	 * 每天凌晨5分执行
	 */
//	@Scheduled(cron = "0 0/3 * * * ?")
//	@Scheduled(cron = "0 5 1 * * ?")
	public void updateDeviceSimInfoMonthTraffic() {
		//4.1.2.2.2	批量号码月流量查询
		String method = "triopi.member.dailyflow.realtime.batch.query";
		try {
			//城市对应的集团编码，应用键对应值，密钥的MAP
			Map<String, CityCmccInfoDTO> cityCmccInfoMap = cityCmccInfoService.getCityCmccInfoMap();
			System.out.println("cityCmccInfoMap: " + cityCmccInfoMap.toString());
			if (cityCmccInfoMap != null && cityCmccInfoMap.size() > 0) {
				Set<String> citySet = cityCmccInfoMap.keySet();
				for (String city : citySet) {
					//获取城市对应的集团编码，应用键对应值，密钥
					CityCmccInfoDTO cityCmccInfoDTO = cityCmccInfoMap.get(city);
					String appKeyValue = cityCmccInfoDTO.getAppKey();
					String secrect = cityCmccInfoDTO.getSecrect();
					String groupCode = cityCmccInfoDTO.getGroupCode();
					//获取终端sim卡信息总数
					Long count = deviceSimInfoService.countDeviceSimInfo(city);
					if (count != null && count > 0) {
						//获取第一个终端sim卡信息,以获取第一个起始ID
						DeviceSimInfoTrafficDTO deviceSimInfoTrafficDTO = deviceSimInfoService.selectFirstDeviceSimInfoTraffic(city);
						if (deviceSimInfoTrafficDTO != null) {
							//默认起始ID(此处减1是根据后端查询语句推算出来的，保证第一个ID也包含在查询结果集内)
							Long startId = deviceSimInfoTrafficDTO.getDeviceSimInfoId() - 1;
							System.out.println("updateDeviceSimInfoMonthTraffic_startId: " + startId);
							//默认结束ID
							long endId = 100L;
							//默认条数
							long rows = 100L;
							//如果开始ID大于默认的结束ID
							if (startId > endId) {
								endId = startId + rows;
							}
							//用总数除以每次默认查询条数，得到查询次数(就是需要循环的次数)
							long num = count / rows;
							//如果查询次数乘乘以默认查询条数，默认次数需要++1
							if (num * rows < count) {
								num++;
							}
							StringBuilder sb = new StringBuilder();
							//分批次查询数据，批量查询sim卡的信息
							for (int i = 0; i < num; i++) {
								System.out.println("startId:" + startId);
								System.out.println("endId:" + endId);
								List<DeviceSimInfoTrafficDTO> trafficList = deviceSimInfoService.listDeviceSimInfoTraffic(city, startId, endId, rows);
								System.out.println("updateDeviceSimInfoMonthTraffic_trafficList.size: " + trafficList.size());
								if (CollectionUtils.isNotEmpty(trafficList)) {
									//获取列表数据最后一个的ID
									DeviceSimInfoTrafficDTO lastTrafficeDTO = trafficList.get(trafficList.size() - 1);
									Long lastActivationTimeId = lastTrafficeDTO.getDeviceSimInfoId();
									//下一起始ID
									startId = lastActivationTimeId;
									endId = endId + rows;
									//将iccid拼接整字符串，用逗号隔开
									for (int j = 0; j < trafficList.size(); j++) {
										DeviceSimInfoTrafficDTO dto = trafficList.get(j);
										String iccid = dto.getIccid();
										if (j > 0) {
											sb.append(",");
										}
										sb.append(iccid);
									}
								}
								String iccids = sb.toString();
								System.out.println("updateDeviceSimInfoMonthTraffic_iccids: " + iccids);
								//将iccidSb的长度清零，重复使用
								sb.setLength(0);
								//获取sim卡当月流量使用情况
								String data = CmccApiUtils.queryByICCID(method, iccids, true, null, appKeyValue, secrect, groupCode);
								if (StringUtils.isBlank(data)) {
									logger.error("DeviceSimInfoSchedule updateDeviceSimInfoMonthTraffic 更新终端sim卡信息当月流量预警失败： 接口返回参数为空");
									continue;
								}
								//转化为JSONObject
								JSONObject dataJsonObj = JSON.parseObject(data);
								//获取msisdnList，以下代码是解析JSON数据并将解析出的数据存入数据
								JSONObject msisdnJsonObj = dataJsonObj.getJSONObject(CmccApiConstant.JSON_KEY_MSISDN_INFO_LIST);
								JSONArray jsonArray = msisdnJsonObj.getJSONArray(CmccApiConstant.JSON_KEY_LIST);
								if (jsonArray != null && jsonArray.size() > 0) {
									List<DeviceSimInfoTrafficDTO> list = new ArrayList<>();
									for (int j = 0; j < jsonArray.size(); j++) {
										JSONObject arrayJsonObj = jsonArray.getJSONObject(j);
										String iccid = arrayJsonObj.getString(CmccApiConstant.JSON_KEY_ICCID);
										JSONObject apnJsonObj = arrayJsonObj.getJSONObject(CmccApiConstant.JSON_KEY_APN_LIST);
										JSONArray apnJsonArray = apnJsonObj.getJSONArray(CmccApiConstant.JSON_KEY_LIST);
										double monthFlow = 0D;
										if (apnJsonArray != null && apnJsonArray.size() > 0) {
											for (int k = 0; k < apnJsonArray.size(); k++) {
												JSONObject usedJsonObj = apnJsonArray.getJSONObject(k);
												//如果pkgInfoList的list列表列的内容不为空，就统计流量
												JSONObject pkgInfoJsonObj = usedJsonObj.getJSONObject(CmccApiConstant.JSON_KEY_PKG_INFO_LIST);
												JSONArray pkgInfoJsonArray = pkgInfoJsonObj.getJSONArray(CmccApiConstant.JSON_KEY_LIST);
												if (pkgInfoJsonArray == null || pkgInfoJsonArray.size() == 0) {
													continue;
												}
												double usedFlow = usedJsonObj.getDoubleValue(CmccApiConstant.JSON_KEY_USED_FLOW);
												monthFlow = monthFlow + usedFlow;
											}
										}
										DeviceSimInfoTrafficDTO trafficDTO = new DeviceSimInfoTrafficDTO();
										trafficDTO.setIccid(iccid);
										// TODO 数据库不存储单位字符 2018-9-18 lq
										trafficDTO.setCurrentMonthTraffic(String.valueOf(monthFlow));
										list.add(trafficDTO);
									}
									System.out.println("updateDeviceSimInfoMonthTraffic_list.size: " + list.size());
									//将当月流量数据保存至数据库
									if (CollectionUtils.isNotEmpty(list)) {
										for (DeviceSimInfoTrafficDTO dto : list) {
											deviceSimInfoService.updateDeviceSimInfoMonthTraffic(dto);
										}
									}
								}
							}
						}
					}
				}
			}
		} catch (ServiceException e) {
			logger.error("DeviceSimInfoSchedule updateDeviceSimInfoMonthTraffic 更新终端sim卡信息当月流量预警失败：" + e.getMessage());
		} catch (CmccApiException e) {
			logger.error("DeviceSimInfoSchedule updateDeviceSimInfoMonthTraffic 更新终端sim卡信息当月流量预警失败：" + e.getMessage());
		}

	}

	/**
	 * 更新终端sim卡信息历史总流量
	 */
//	@Scheduled(cron = "0 0/3 * * * ?")
//	@Scheduled(cron = "0 0 1 1 * ?")
	public void updateDeviceSimInfoHistoryTraffic() {
		//4.2.2.4	单个号码历史月流量查询
		String method = "triopi.member.monthflow.realtime.query";
		try {
			//城市对应的集团编码，应用键对应值，密钥的MAP
			Map<String, CityCmccInfoDTO> cityCmccInfoMap = cityCmccInfoService.getCityCmccInfoMap();
			System.out.println("cityCmccInfoMap: " + cityCmccInfoMap.toString());
			if (cityCmccInfoMap != null && cityCmccInfoMap.size() > 0) {
				Set<String> citySet = cityCmccInfoMap.keySet();
				for (String city : citySet) {
					//获取城市对应的集团编码，应用键对应值，密钥
					CityCmccInfoDTO cityCmccInfoDTO = cityCmccInfoMap.get(city);
					String appKeyValue = cityCmccInfoDTO.getAppKey();
					String secrect = cityCmccInfoDTO.getSecrect();
					String groupCode = cityCmccInfoDTO.getGroupCode();
					//获取终端sim卡信息总数
					Long count = deviceSimInfoService.countDeviceSimInfo(city);;
					if (count != null && count > 0) {
						//获取第一个终端sim卡信息,以获取第一个起始ID
						DeviceSimInfoTrafficDTO deviceSimInfoTrafficDTO = deviceSimInfoService.selectFirstDeviceSimInfoTraffic(city);
						if (deviceSimInfoTrafficDTO != null) {
							//获取近期六个月的月份数据，数据格式为yyyyMM
							long currentTimeMillis = System.currentTimeMillis();
							String yearMonth = DateUtils.longTimeStampToStringDate(currentTimeMillis, DateFormatConstant.DATE_YEAR_MONTH);
							//获取年
							String year = yearMonth.substring(0, 4);
							int intYear = Integer.parseInt(year);
							//获取月
							String month = yearMonth.substring(4, yearMonth.length());
							int intMonth = Integer.parseInt(month);
							String[] nearSixMonth = DateUtils.getNearSixMonth(intYear, intMonth);
							System.out.println("nearSixMonth:" + nearSixMonth);
							//获取上一个月月份
							String lastDateOfMonth = DateUtils.getLastDateOfMonth(intYear, intMonth, DateFormatConstant.DATE_YEAR_MONTH);
							//默认起始ID(此处减1是根据后端查询语句推算出来的，保证第一个ID也包含在查询结果集内)
							Long startId = deviceSimInfoTrafficDTO.getDeviceSimInfoId() - 1;
							//默认结束ID
							long endId = 100L;
							//默认条数
							long rows = 100L;
							//如果开始ID大于默认的结束ID
							if (startId > endId) {
								endId = startId + rows;
							}
							//用总数除以每次默认查询条数，得到查询次数(就是需要循环的次数)
							long num = count / rows;
							//如果查询次数乘乘以默认查询条数，默认次数需要++1
							if (num * rows < count) {
								num++;
							}
							//分批次查询数据，批量查询sim卡的信息
							for (int i = 0; i < num; i++) {
								List<DeviceSimInfoTrafficDTO> trafficList = deviceSimInfoService.listDeviceSimInfoTraffic(city, startId, endId, rows);
								if (CollectionUtils.isNotEmpty(trafficList)) {
									for (int j = 0; j < trafficList.size(); j++) {
										DeviceSimInfoTrafficDTO trafficDTO = trafficList.get(j);
										//iccid
										String iccid = trafficDTO.getIccid();
										if (StringUtils.isBlank(iccid)) {
											continue;
										}
										//历史总流量
										String historicalTotalTraffic = trafficDTO.getHistoricalTotalTraffic();
										//如果历史总流量为空，就查询近期六个月的流量数据（因为移动提供的接口，只能查询近期六个月的流量）
										if (StringUtils.isBlank(historicalTotalTraffic)) {
											double tempFlow = 0.0;
											for (int k = 0; k < nearSixMonth.length; k++) {
												String	str = CmccApiUtils.queryByICCID(method, iccid, false, nearSixMonth[k], appKeyValue, secrect, groupCode);
												double flow = parseDailyFlow(str);
												tempFlow = tempFlow + flow;
											}
											// TODO 数据库不存储单位字符 2018-9-18 lq
											trafficDTO.setHistoricalTotalTraffic(String.valueOf(tempFlow));
											deviceSimInfoService.updateDeviceSimInfoHistoryTraffic(trafficDTO);
										} else {
											//如果不为空，就查询上一个月的流量+以前的总流量
											double historicalFlow = Double.parseDouble(historicalTotalTraffic.replaceAll(BusinessConstant.DATA_UNIT_M, ""));
											String	resultStr = CmccApiUtils.queryByICCID(method, iccid, false, lastDateOfMonth, appKeyValue, secrect, groupCode);
											double flow = parseDailyFlow(resultStr);
											historicalFlow = historicalFlow + flow;
											// TODO 数据库不存储单位字符 2018-9-18 lq
											trafficDTO.setHistoricalTotalTraffic(String.valueOf(historicalFlow));
											deviceSimInfoService.updateDeviceSimInfoHistoryTraffic(trafficDTO);
										}
									}
								}
							}
	}
}
				}
						}
		} catch (ServiceException e) {
			logger.error("DeviceSimInfoSchedule updateDeviceSimInfoHistoryTraffic 更新终端sim卡信息历史总流量：" + e.getMessage());
		} catch (CmccApiException e) {
			logger.error("DeviceSimInfoSchedule updateDeviceSimInfoHistoryTraffic 更新终端sim卡信息历史总流量：" + e.getMessage());
		} catch (Exception e) {
			logger.error("DeviceSimInfoSchedule updateDeviceSimInfoHistoryTraffic 更新终端sim卡信息历史总流量：" + e.getMessage());
		}

	}

	/**
	 * 解析单个号码历史月流量
	 *
	 * @param jsonStr JSON格式字符串
	 * @return double(历史月流量 ）
	 */
	private double parseDailyFlow(String jsonStr) {
		if (StringUtils.isBlank(jsonStr)) {
			throw new NullPointerException("输入JSON格式字符串不能为空");
		}
		JSONObject jsonObject = JSON.parseObject(jsonStr);
		JSONArray apnInfoJsonArray = jsonObject.getJSONArray("apnInfo");
		double tempFlow = 0.0;
		if (apnInfoJsonArray != null && apnInfoJsonArray.size() > 0) {
			for (int k = 0; k < apnInfoJsonArray.size(); k++) {
				JSONObject apnJsonObj = apnInfoJsonArray.getJSONObject(k);
				if (apnJsonObj != null) {
					JSONObject monthlyJsonObj = apnJsonObj.getJSONObject("monthlyList");
					if (monthlyJsonObj != null) {
						JSONArray listJsonArray = monthlyJsonObj.getJSONArray("list");
						if (listJsonArray != null && listJsonArray.size() > 0) {
							for (int m = 0; m < listJsonArray.size(); m++) {
								JSONObject jsonObj = listJsonArray.getJSONObject(m);
								String usedFlow = jsonObj.getString("usedFlow");
								if (StringUtils.isBlank(usedFlow)) {
									continue;
								}
								double flow = Double.parseDouble(usedFlow);
								tempFlow = tempFlow + flow;
							}
						}
					}
				}
			}
		}
		return tempFlow;
	}

}
